﻿Shader "RenderDemo/Wave"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            Cull off
            Tags {"LightMode" = "ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "UnityLightingCommon.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
                float3 lightDir : TEXCOORD2;
                float3 viewDir : TEXCOORD3;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            fixed3 CaculatePos(fixed A, fixed w, fixed fi, fixed t, fixed2 direction, fixed3 p){
                direction = normalize(direction);
                float H = A * sin( dot(p.xz, direction) * w + t * fi);
                return fixed3(0, H, 0);
            }

            fixed3 CaculateNormal(fixed A, fixed w, fixed fi, fixed t, fixed2 direction, fixed3 p){
                direction = normalize(direction);
                fixed3 newNormal = fixed3(1, 1, 1);
                newNormal.x = -w * direction.x * A * cos(dot(direction, p.xz) * w + t * fi);
                newNormal.y = -w * direction.y * A * cos(dot(direction, p.xz) * w + t * fi);
                return newNormal;
            }

            v2f vert (appdata v)
            {
                v2f o;
                float w = 0.15;
                float fi = 2;
                float A = 1;
                
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex);
                float3 disPos = float3(0,0,0);
                disPos += CaculatePos(A/8, w, fi, _Time.x * 80, fixed2(-1, -1), worldPos);
                disPos += CaculatePos(A, w, fi, _Time.x * 60, fixed2(2, -0.5), worldPos);
                disPos += CaculatePos(A, w, fi, _Time.x * 20, fixed2(1, -2), worldPos);
                disPos += CaculatePos(A * 2, w, fi, _Time.x * 40, fixed2(1, -1), worldPos);
                fixed3 n = fixed3(0,1,0);
                n += CaculateNormal(A/8, w, fi, _Time.x * 80, fixed2(-1, -1), worldPos);
                n += CaculateNormal(A, w, fi, _Time.x * 60, fixed2(2, -0.5), worldPos);
                n += CaculateNormal(A, w, fi, _Time.x * 20, fixed2(1, -2), worldPos);
                n += CaculateNormal(A * 2, w, fi, _Time.x * 40, fixed2(1, -1), worldPos);

                v.vertex.xyz = mul(unity_WorldToObject, float4(worldPos + disPos, 1));
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.normal = normalize(n);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.lightDir = ObjSpaceLightDir(v.vertex);
                o.viewDir = ObjSpaceViewDir(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // fixed4 col = tex2D(_MainTex, i.uv);
                // i.lightDir = normalize(i.lightDir);
                // i.viewDir = normalize(i.viewDir);
                // half3 h = normalize(i.lightDir + i.viewDir);
                // float nh = max(0, dot(h, i.normal));
                // float diff = max(0, dot(i.normal, i.lightDir));
                // col.rgb = col.rgb * _LightColor0.rgb * diff;
                // return col;

                fixed3 worldNormal = normalize(i.normal);
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                fixed3 lambert = 0.5 * max(0, dot(worldNormal, worldLightDir)) + 0.5;
                fixed3 diffuse = lambert * _LightColor0.xyz;
                return fixed4(diffuse, 1);
            }
            ENDCG
        }
    }
}
